home *** CD-ROM | disk | FTP | other *** search
/ Aminet 32 / Aminet 32 (1999)(Schatztruhe)[!][Aug 1999].iso / Aminet / dev / lang / Python151_Src.lha / Python1.5_Source / Amiga / unixemul.c < prev    next >
C/C++ Source or Header  |  1998-12-25  |  7KB  |  352 lines

  1. /**************************************************************\
  2. **                                                            **
  3. **  UNIX 'emulation' functions for AmigaDOS                   **
  4. **                                                            **
  5. **  Made by Irmen de Jong (irmen@bigfoot.com)                 **
  6. **                                                            **
  7. **  21-jan-98: Created. Moved some functions from             **
  8. **             Modules/Amigamodule.c to here.                 **
  9. **  25-dec-98: Added I-Net 225 support                        **
  10. **             Added ftruncate (but not used due to bugs)     **
  11. **                                                            **
  12. **  NOTE: Don't forget __io2errno conversion!!!!!!!!!!!!!!!!  **
  13. **                                                            **
  14. \**************************************************************/
  15.  
  16. #include <sys/stat.h>
  17. #include <proto/dos.h>
  18. #include <proto/exec.h>
  19. #include <dos/dostags.h>
  20. #include <exec/execbase.h>
  21. #ifdef AMITCP
  22. #include <proto/usergroup.h>
  23. #include <proto/socket.h>
  24. #endif
  25. #ifdef INET225
  26. #include <proto/socket.h>
  27. static int _OSERR;
  28. #endif
  29. #include "Python.h"
  30.  
  31. /************ Utility functions *************/
  32.  
  33. /*** checkLink: check for link loops and other errors ***/
  34. static BOOL checkLink(char *from, BPTR to, BOOL root)
  35. {
  36.     struct FileInfoBlock __aligned fib;
  37.  
  38.     if(Examine(to,&fib))
  39.     {
  40.         if(fib.fib_EntryType>0)
  41.         {
  42.             // directory! Check some things (loops etc)
  43.             char* pp;
  44.             char p;
  45.             BPTR fromLock,temp;
  46.  
  47.             // only superuser may link directories
  48.             if(!root)
  49.             {
  50.                 errno=EPERM; return FALSE;
  51.             }
  52.  
  53.             pp = PathPart(from);
  54.             p = *pp;
  55.             *pp = 0;
  56.             fromLock=Lock(from,SHARED_LOCK);
  57.             *pp=p;
  58.  
  59.             if(fromLock)
  60.             {
  61.                 do {
  62.                     if(SameLock(fromLock,to)==LOCK_SAME)
  63.                     {
  64.                         UnLock(fromLock);
  65.                         errno = ELOOP;
  66.                         return FALSE;       // link loop
  67.                     }
  68.  
  69.                     temp = fromLock;
  70.                     fromLock = ParentDir(fromLock);
  71.                     UnLock(temp);
  72.                 } while (fromLock);
  73.  
  74.                 return TRUE;       // dir, OK.
  75.             }
  76.             else errno=__io2errno(_OSERR=IoErr());
  77.         }
  78.         else return TRUE;      // file, OK.
  79.     }
  80.     else errno=__io2errno(_OSERR=IoErr());
  81.  
  82.     return FALSE;
  83. }
  84.  
  85.  
  86. /************ link(2) : make a hard link ************/
  87.  
  88. /* LINK: make hardlink from 'from' to 'to' (to must exist, from is new) */
  89. /* 'from' may not be a directory if you are not the super-user. */
  90. /* 0=ok, -1=err */
  91. int link(const char *to, const char *from)
  92. {
  93.     BOOL root;
  94.     BPTR toLock;
  95.  
  96.     /* are we superuser? */
  97. #ifdef AMITCP
  98.     if (!checkusergrouplib())
  99. #else
  100.     if (!checksocketlib())
  101. #endif
  102.     {
  103.         PyErr_Clear();
  104.         root=TRUE;  /* can't tell... so be root */
  105.     }
  106.     else if(getuid()==0) root = TRUE;
  107.     else root=FALSE;
  108.  
  109.     if(toLock=Lock(to,SHARED_LOCK))
  110.     {
  111.         if(checkLink(from,toLock,root))
  112.         {
  113.             if(MakeLink(from,(LONG)toLock,FALSE))
  114.             {
  115.                 UnLock(toLock);
  116.                 return 0;
  117.             }
  118.             else errno=__io2errno(_OSERR=IoErr());
  119.         }
  120.         UnLock(toLock);
  121.     }
  122.     else errno=__io2errno(_OSERR=IoErr());
  123.     
  124.     return -1;
  125. }
  126.  
  127. /************** symlink(2): create symbolic (soft) link ********/
  128. int symlink(const char *to, const char *from)
  129. {
  130.     /* symbolic link 'from' is created to 'to' */
  131.     /* 0=ok, else -1 + errno */
  132.  
  133.     BPTR toLock;
  134.  
  135.     if(toLock=Lock(to,SHARED_LOCK))
  136.     {
  137.         if(checkLink(from,toLock,TRUE))
  138.         {
  139.             UnLock(toLock);
  140.             if(MakeLink(from,(LONG)to,TRUE)) return 0;
  141.             else errno=__io2errno(_OSERR=IoErr());
  142.         }
  143.         else UnLock(toLock);
  144.     }
  145.     else errno=__io2errno(_OSERR=IoErr());
  146.     
  147.     return -1;
  148. }
  149.  
  150.  
  151.  
  152. /************** readlink(2): read value of a symbolic link ***********/
  153.  
  154. int readlink(const char *path, char *buf, int bufsiz)
  155. {
  156.     struct MsgPort *port;
  157.     struct stat st;
  158.  
  159.     if(!(port=DeviceProc(path)))
  160.     {
  161.         errno=EIO; return -1;
  162.     }
  163.  
  164.     buf[bufsiz-1]=0;
  165.     errno=0;
  166.  
  167.     if(lstat(path,&st)>=0)
  168.     {
  169.         if(S_ISLNK(st.st_mode))
  170.         {
  171.             char c;
  172.             BPTR dirlock;
  173.             BPTR olddir;
  174.             char *p;
  175.             char *link;
  176.  
  177.             p = PathPart(path);
  178.             link = FilePart(path);
  179.             c = *p; *p='\0';
  180.             dirlock=Lock(path,ACCESS_READ); *p=c;
  181.             if(dirlock)
  182.             {
  183.                 olddir=CurrentDir(dirlock);
  184.  
  185.                 if(!ReadLink(port,dirlock,link,buf,bufsiz))
  186.                     errno=__io2errno(_OSERR=IoErr());
  187.  
  188.                 dirlock=CurrentDir(olddir);
  189.                 UnLock(dirlock);
  190.             }   
  191.             else errno=__io2errno(_OSERR=IoErr());
  192.         }
  193.         else errno=EINVAL;
  194.     }
  195.  
  196.     if(errno!=0) return -1;
  197.  
  198.     if(buf[bufsiz-1]==0) return strlen(buf);
  199.     else return bufsiz;
  200. }
  201.  
  202.  
  203.  
  204. /** custom mkdir() implementation **/
  205. /** This version actually sets protection bits **/
  206. #ifndef INET225
  207. int my_mkdir(const char* path, int p)
  208. {
  209. #ifdef AMITCP
  210.     if(checkusergrouplib()) p &= ~getumask();
  211. #else
  212.     if(checksocketlib()) p &= ~getumask();
  213. #endif
  214.     else PyErr_Clear();
  215.  
  216.     if(0==mkdir(path))
  217.     {
  218.         return chmod(path,p);
  219.     }
  220.     return -1;
  221. }
  222. #endif /* !INET225 */
  223.  
  224. int uname(struct utsname *u)
  225. {
  226.     int res;
  227.  
  228.     strcpy(u->sysname,"AmigaDOS");
  229.     strcpy(u->machine,"m68k");
  230.     if (!checksocketlib())
  231.     {
  232.         char *v;
  233.         PyErr_Clear();
  234.         res=0; v=getenv("HOSTNAME");
  235.         if(v) strcpy(u->nodename, v);
  236.         else strcpy(u->nodename, "localhost");
  237.     }
  238.     else res = gethostname(u->nodename, _UNAME_BUFLEN-1);
  239.     if(res>=0)
  240.     {
  241.         LONG ver_major = SysBase->LibNode.lib_Version;
  242.         LONG ver_minor = SysBase->SoftVer;
  243.         sprintf (u->release, "%d.%d", ver_major,ver_minor);
  244.         if(ver_major<36)
  245.             strcpy(u->version,"1");
  246.         else if(ver_major<39)
  247.             strcpy(u->version,"2");
  248.         else 
  249.             strcpy(u->version,"3");
  250.     }
  251.     return 0;
  252. }
  253.  
  254.  
  255. #ifndef INET225
  256. FILE *popen(const char *command, const char *type)
  257. {
  258.     char file[50];
  259.  
  260.     FILE *fh;
  261.  
  262.     static int num = 1;
  263.  
  264.     if((type[0]!='r') && (type[0]!='w'))
  265.     {
  266.         errno=EINVAL;
  267.         return 0;
  268.     }
  269.         
  270.     sprintf(file,"PIPE:Py_%ld_%ld",num++,FindTask(0));
  271.  
  272.     if(fh=fopen(file,type))
  273.     {
  274.         BPTR fh2;
  275.         LONG mode=MODE_NEWFILE; /* 'r'-peer must write */
  276.  
  277.         if(type[0]=='w') mode=MODE_OLDFILE; /* peer must read */
  278.  
  279.         if(fh2=Open(file,mode))
  280.         {
  281.             BPTR fh3;
  282.             if(type[0]=='r')
  283.             {
  284.                 /* execute command with output to fh */
  285.                 fh3=Open("*",MODE_OLDFILE); /* should use CONSOLE: */
  286.                 if(fh3 && (0==SystemTags(command,SYS_Asynch,TRUE,SYS_Output,fh2,
  287.                                     SYS_Input,fh3,TAG_DONE)))
  288.                 {
  289.                     return fh;
  290.                 }
  291.             }
  292.             else /** if(type[0]=='w') **/
  293.             {
  294.                 /* execute command with input from fh */
  295.                 fh3=Open("*",MODE_NEWFILE); /* should use CONSOLE: */
  296.                 if(fh3 && (0==SystemTags(command,SYS_Asynch,TRUE,SYS_Input,fh2,
  297.                                     SYS_Output,fh3,TAG_DONE)))
  298.                 {
  299.                     return fh;
  300.                 }
  301.             }
  302.             fclose(fh); Close(fh2); if(fh3) Close(fh3);
  303.             errno=EAGAIN;
  304.             return 0;
  305.         }
  306.         fclose(fh);
  307.     }
  308.     errno=ENOENT;
  309.     return 0;
  310. }
  311.  
  312. int pclose(FILE *stream)
  313. {
  314.     if(stream)
  315.     {
  316.         fclose(stream);
  317.         return 0;
  318.     }
  319.     errno=EINVAL;
  320.     return -1;  
  321. }
  322.  
  323. #endif /* INET225 */
  324.  
  325.  
  326. /*************** ftruncate is not yet used because of bugs in the OS FileSystem :-( ***/
  327.  
  328. #if 0
  329.  
  330. int ftruncate(int fd, long newlength)
  331. {
  332.   struct UFB *ufb;
  333.  
  334.   /*
  335.    * find the ufb *
  336.    */
  337.   if ((ufb = __chkufb(fd)) != NULL && !(ufb->ufbflg & UFB_SOCK))
  338.   {
  339.     if(-1==SetFileSize(ufb->ufbfh,newlength,OFFSET_BEGINNING))
  340.     {
  341.         set_errno(IoErr());
  342.         return -1;
  343.     }
  344.     return 0;
  345.   }
  346.   
  347.   errno = EINVAL;
  348.   return -1;
  349. }
  350.  
  351. #endif
  352.